﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Web;

namespace Als.Pay
{
    public static class RequestUtility
    {

        public static FileStream GetFileStream(string fileName)
        {
            FileStream stream = null;
            if (!(string.IsNullOrEmpty(fileName) || !System.IO.File.Exists(fileName)))
            {
                stream = new FileStream(fileName, FileMode.Open);
            }
            return stream;
        }

        public static string HttpPost(string url, CookieContainer cookieContainer = null, Dictionary<string, string> formData = null, Encoding encoding = null)
        {
            string queryString = RequestUtility.GetQueryString(formData);
            byte[] buffer = formData == null ? new byte[0] : Encoding.UTF8.GetBytes(queryString);
            MemoryStream memoryStream = new MemoryStream();
            memoryStream.Write(buffer, 0, buffer.Length);
            memoryStream.Seek(0L, SeekOrigin.Begin);
            return RequestUtility.HttpPost(url, cookieContainer, (Stream)memoryStream, (Dictionary<string, string>)null, (string)null, encoding);
        }

        public static string HttpPost(string url, CookieContainer cookieContainer = null, Stream postStream = null, Dictionary<string, string> fileDictionary = null, string refererUrl = null, Encoding encoding = null)
        {
            HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
            httpWebRequest.Method = "POST";
            int num;
            if (fileDictionary != null && fileDictionary.Count > 0)
            {
                postStream = (Stream)new MemoryStream();
                string str1 = "----" + DateTime.Now.Ticks.ToString("x");
                string format = "\r\n--" + str1 + "\r\nContent-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: application/octet-stream\r\n\r\n";
                foreach (KeyValuePair<string, string> keyValuePair in fileDictionary)
                {
                    try
                    {
                        string fileName = keyValuePair.Value;
                        using (FileStream fileStream = GetFileStream(fileName))
                        {
                            string str2 = string.Format(format, (object)keyValuePair.Key, (object)fileName);
                            byte[] bytes = Encoding.ASCII.GetBytes(postStream.Length == 0L ? str2.Substring(2, str2.Length - 2) : str2);
                            postStream.Write(bytes, 0, bytes.Length);
                            byte[] buffer = new byte[1024];
                            num = 0;
                            int count;
                            while ((count = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                                postStream.Write(buffer, 0, count);
                        }
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
                byte[] bytes1 = Encoding.ASCII.GetBytes("\r\n--" + str1 + "--\r\n");
                postStream.Write(bytes1, 0, bytes1.Length);
                httpWebRequest.ContentType = string.Format("multipart/form-data; boundary={0}", (object)str1);
            }
            else
                httpWebRequest.ContentType = "application/x-www-form-urlencoded";
            httpWebRequest.ContentLength = postStream != null ? postStream.Length : 0L;
            httpWebRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
            httpWebRequest.KeepAlive = true;
            if (!string.IsNullOrEmpty(refererUrl))
                httpWebRequest.Referer = refererUrl;
            httpWebRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36";
            if (cookieContainer != null)
                httpWebRequest.CookieContainer = cookieContainer;
            if (postStream != null)
            {
                postStream.Position = 0L;
                Stream requestStream = ((WebRequest)httpWebRequest).GetRequestStream();
                byte[] buffer = new byte[1024];
                num = 0;
                int count;
                while ((count = postStream.Read(buffer, 0, buffer.Length)) != 0)
                    requestStream.Write(buffer, 0, count);
                postStream.Close();
            }
            HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            if (cookieContainer != null)
                httpWebResponse.Cookies = cookieContainer.GetCookies(httpWebResponse.ResponseUri);
            using (Stream responseStream = httpWebResponse.GetResponseStream())
            {
                using (StreamReader streamReader = new StreamReader(responseStream, encoding ?? Encoding.GetEncoding("utf-8")))
                    return streamReader.ReadToEnd();
            }
        }

        public static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            return true;
        }

        public static HttpWebRequest GetWebRequest(string url, string method, string cerPassword = null, string cerPath = null)
        {
            HttpWebRequest request = null;
            if (url.Contains("https"))
            {
                ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                request = (HttpWebRequest)WebRequest.CreateDefault(new Uri(url));
                try
                {
                    if (cerPassword != null)
                    {
                        X509Certificate2 certificate = new X509Certificate2(cerPath, cerPassword, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet);
                        request.ClientCertificates.Add(certificate);
                    }
                }
                catch (Exception exception)
                {
                }
            }
            else
            {
                request = (HttpWebRequest)WebRequest.Create(url);
            }
            request.ServicePoint.Expect100Continue = false;
            request.Method = method;
            request.KeepAlive = true;
            request.UserAgent = "Hishop";
            return request;
        }

        public static string DoPost(string url, string value, string cerPassword = null, string cerPath = null)
        {
            HttpWebRequest request = GetWebRequest(url, "POST", cerPassword, cerPath);
            request.ContentType = "application/x-www-form-urlencoded;charset=utf-8";
            byte[] bytes = Encoding.UTF8.GetBytes(value);
            Stream requestStream = request.GetRequestStream();
            requestStream.Write(bytes, 0, bytes.Length);
            requestStream.Close();
            HttpWebResponse rsp = (HttpWebResponse)request.GetResponse();
            return GetResponseAsString(rsp, Encoding.UTF8);
        }

        public static string GetResponseAsString(HttpWebResponse rsp, Encoding encoding)
        {
            Stream responseStream = null;
            StreamReader reader = null;
            string str;
            try
            {
                responseStream = rsp.GetResponseStream();
                reader = new StreamReader(responseStream, encoding);
                str = reader.ReadToEnd();
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                }
                if (responseStream != null)
                {
                    responseStream.Close();
                }
                if (rsp != null)
                {
                    rsp.Close();
                }
            }
            return str;
        }

        public static string HttpPost(string url, string cert, string certpwd, CookieContainer cookieContainer = null, Stream postStream = null, Dictionary<string, string> fileDictionary = null, string refererUrl = null, Encoding encoding = null)
        {
            HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
            X509Certificate2 x509Certificate2 = new X509Certificate2(cert, certpwd, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet);
            httpWebRequest.ClientCertificates.Add((X509Certificate)x509Certificate2);
            httpWebRequest.Method = "POST";
            httpWebRequest.Timeout = 6000;
            httpWebRequest.ContentType = "text/xml";
            httpWebRequest.ContentLength = postStream != null ? postStream.Length : 0L;
            if (!string.IsNullOrEmpty(refererUrl))
                httpWebRequest.Referer = refererUrl;
            if (cookieContainer != null)
                httpWebRequest.CookieContainer = cookieContainer;


            System.IO.File.AppendAllText(HttpContext.Current.Server.MapPath("~/err.log"), cert);
            if (postStream != null)
            {
                postStream.Position = 0L;
                Stream requestStream = ((WebRequest)httpWebRequest).GetRequestStream();
                byte[] buffer = new byte[1024];
                int count;
                while ((count = postStream.Read(buffer, 0, buffer.Length)) != 0)
                    requestStream.Write(buffer, 0, count);
                postStream.Close();
            }
            System.IO.File.AppendAllText(HttpContext.Current.Server.MapPath("~/err.log"), "117");
            HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            System.IO.File.AppendAllText(HttpContext.Current.Server.MapPath("~/err.log"), "123");
            if (cookieContainer != null)
                httpWebResponse.Cookies = cookieContainer.GetCookies(httpWebResponse.ResponseUri);
            using (Stream responseStream = httpWebResponse.GetResponseStream())
            {
                using (StreamReader streamReader = new StreamReader(responseStream, encoding ?? Encoding.GetEncoding("utf-8")))
                    return streamReader.ReadToEnd();
            }
        }

        public static bool IsWeixinClientRequest(this HttpContext httpContext)
        {
            return !string.IsNullOrEmpty(httpContext.Request.UserAgent) && httpContext.Request.UserAgent.Contains("MicroMessenger");
        }

        public static string GetQueryString(this Dictionary<string, string> formData)
        {
            if (formData == null || formData.Count == 0)
                return "";
            StringBuilder stringBuilder = new StringBuilder();
            int num = 0;
            foreach (KeyValuePair<string, string> keyValuePair in formData)
            {
                ++num;
                stringBuilder.AppendFormat("{0}={1}", (object)keyValuePair.Key, (object)keyValuePair.Value);
                if (num < formData.Count)
                    stringBuilder.Append("&");
            }
            return ((object)stringBuilder).ToString();
        }

        public static string HtmlEncode(this string html)
        {
            return HttpUtility.HtmlEncode(html);
        }

        public static string HtmlDecode(this string html)
        {
            return HttpUtility.HtmlDecode(html);
        }

        public static string UrlEncode(this string url)
        {
            return HttpUtility.UrlEncode(url);
        }

        public static string UrlDecode(this string url)
        {
            return HttpUtility.UrlDecode(url);
        }

    }
}
